//#define TEST_API
//#define NO_SDK

using System.Linq;
using Cysharp.Threading.Tasks;

#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
#elif WEIXINMINIGAME
using WeChatWASM;
#elif BYTEDANCEMINIGAME
using TTSDK;
#elif QGMINIGAME
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
#elif GOOGLE_PLAY
#else
#endif
#else
#endif
#else
#endif

namespace Runtime.SDK
{
    public static partial class DFR_API
    {
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
#elif WEIXINMINIGAME
        //Touch结束的回调事件
        private static void OnTouchEnd(OnTouchStartListenerResult result)
        {
            UnityEngine.Debug.Log("触摸结束");

            var pageX = result.changedTouches[0].pageX;
            var pageY = result.changedTouches[0].pageY;
            foreach (var item in result.changedTouches)
            {
                UnityEngine.Debug.Log("TouchEnd认为我点击的横坐标" + item.pageX);
                UnityEngine.Debug.Log("TouchEnd认为我点击的纵坐标" + item.pageY);
            }

            //我需要根据changedTouches中item的坐标，来判断我点击的区域是不是在按钮的范围内，如果是的话，才发起订阅
            //item.pageX和item.clientX这类坐标目前测试下来是同一个值，故此这里只选择其中的item.pageX作为判断依据
            //需要注意的是，item.pageX和item.clientX都是以屏幕的最左下角为原点，向右为X轴正方向，向上为Y轴正方向，和官方文档所说的左上角为原点并不相同

            //屏幕尺寸
            var screenWidth = (float)WX.GetSystemInfoSync().screenWidth;
            var screenHeight = (float)WX.GetSystemInfoSync().screenHeight;
            var pixelRatio = WX.GetSystemInfoSync().pixelRatio;

            UnityEngine.Debug.Log("屏幕的宽度" + screenWidth);
            UnityEngine.Debug.Log("屏幕的高度" + screenHeight);
            UnityEngine.Debug.Log("一种缩放比？" + pixelRatio);

            //这一对宽高和pageX、pageY坐一桌
            var pageWidth = screenWidth * pixelRatio;
            var pageHeight = screenHeight * pixelRatio;

            //这个值代表着我点击的位置，在屏幕上的比例，例如ratio为0.5，代表我点击的位置的横坐标在屏幕的中间
            var ratioW = pageX / pageWidth;
            var ratioH = pageY / pageHeight;

            UnityEngine.Debug.Log("宽度和屏幕的比例" + ratioW);
            UnityEngine.Debug.Log("高度和屏幕的比例" + ratioH);

            //我还需要计算一个比例，因为真机的屏幕尺寸和编辑器内不同
            var ratioHEditor = screenHeight / 1280f;
            var ratioWEditor = screenWidth / 720f;

            //那么接下来我只要判断，在screenWidth和screenHeight乘以这个比例之后的值，是否在按钮的范围内即可
            //这四个值是理想状态下，订阅版本按钮的左下角和右上角的坐标
            double minLeftVersion = screenWidth / 2 + 106 * ratioHEditor - 50 * ratioHEditor;
            double maxLeftVersion = screenWidth / 2 + 106 * ratioHEditor + 50 * ratioHEditor;
            double minTopVersion = screenHeight / 2 - 12 * ratioHEditor - 32 * ratioHEditor;
            double maxTopVersion = screenHeight / 2 - 12 * ratioHEditor + 32 * ratioHEditor;

            //这四个值是理想状态下，订阅体力按钮的左下角和右上角的坐标
            double minLeftVitality = screenWidth / 2 + 106 * ratioHEditor - 50 * ratioHEditor;
            double maxLeftVitality = screenWidth / 2 + 106 * ratioHEditor + 50 * ratioHEditor;
            double minTopVitality = screenHeight / 2 - 102 * ratioHEditor - 32 * ratioHEditor;
            double maxTopVitality = screenHeight / 2 - 102 * ratioHEditor + 32 * ratioHEditor;

            UnityEngine.Debug.Log("minLeft" + minLeftVitality);
            UnityEngine.Debug.Log("maxLeft" + maxLeftVitality);
            UnityEngine.Debug.Log("minTop" + minTopVitality);
            UnityEngine.Debug.Log("maxTop" + maxTopVitality);

            if (screenWidth * ratioW >= minLeftVersion && screenWidth * ratioW <= maxLeftVersion && screenHeight * ratioH >= minTopVersion && screenHeight * ratioH <= maxTopVersion)
            {
                SubscribeVersionMessage();
            }
            else
            {
                UnityEngine.Debug.Log("此次点击并不在订阅版本按钮的范围内");
            }

            if (screenWidth * ratioW >= minLeftVitality && screenWidth * ratioW <= maxLeftVitality && screenHeight * ratioH >= minTopVitality && screenHeight * ratioH <= maxTopVitality)
            {
                SubscribeVitalityMessage();
            }
            else
            {
                UnityEngine.Debug.Log("此次点击并不在订阅体力按钮的范围内");
            }
        }

        private static void OnTouchEndInMainMenu(OnTouchStartListenerResult result)
        {
            UnityEngine.Debug.Log("主界面触摸结束");

            SubscribeVitalityMessageInMainMenu();
        }
#elif BYTEDANCEMINIGAME
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
#elif GOOGLE_PLAY
#else
#endif
#else
#endif
#else
#endif
        public static SubscribeVersion subscribeVersionCallBack;
        public static SubscribeVitality subscribeVitalityCallBack;
        public static SubscribeVitality subscribeVitalityInMainMenuCallBack;
        public delegate UniTaskVoid SubscribeVersion();
        public delegate UniTaskVoid SubscribeVitality();

        //于微信中，用户必须发生点击行为或者发起支付回调后，才可以调起订阅消息界面，故此添加TouchEnd的监听，当用户点击屏幕后，尝试订阅系统消息
        public static async UniTask AddTouchEndListener()
        {
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
            await UniTask.Yield();
#elif WEIXINMINIGAME
            UnityEngine.Debug.Log("尝试监听触摸事件");
            WX.OnTouchEnd(OnTouchEnd);
            await UniTask.Yield();
#elif BYTEDANCEMINIGAME
            await UniTask.Yield();
#elif QGMINIGAME
            await UniTask.Yield();
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
            await UniTask.Yield();
#elif GOOGLE_PLAY
            await UniTask.Yield();
#else
#endif
#else
            await UniTask.Yield();
#endif
#else
            await UniTask.Yield();
#endif
        }

        public static async UniTask AddTouchEndListenerInMainMenu()
        {
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
            await UniTask.Yield();
#elif WEIXINMINIGAME
            UnityEngine.Debug.Log("尝试监听触摸事件");
            WX.OnTouchEnd(OnTouchEndInMainMenu);
            await UniTask.Yield();
#elif BYTEDANCEMINIGAME
            await UniTask.Yield();
#elif QGMINIGAME
            await UniTask.Yield();
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
            await UniTask.Yield();
#elif GOOGLE_PLAY
            await UniTask.Yield();
#else
#endif
#else
            await UniTask.Yield();
#endif
#else
            await UniTask.Yield();
#endif
        }

        //微信订阅版本消息
        public static void SubscribeVersionMessage()
        {
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
#elif WEIXINMINIGAME
            UnityEngine.Debug.Log("我点在了订阅版本按钮的范围内");
            //尝试订阅系统消息
            UnityEngine.Debug.Log("尝试订阅系统消息");

            RequestSubscribeSystemMessageOption requestSubscribeSystemMessageOption = new RequestSubscribeSystemMessageOption();
            requestSubscribeSystemMessageOption.msgTypeList = new string[] {
                    "SYS_MSG_TYPE_WHATS_NEW"
                };
            requestSubscribeSystemMessageOption.success = (res) =>
            {
                UnityEngine.Debug.Log("订阅接口调用成功");

                if (res.Values.First() == "accept")
                {
                    UnityEngine.Debug.Log("用户允许了消息订阅");
                    subscribeVersionCallBack?.Invoke();
                }
                else if (res.Values.First() == "reject")
                {
                    UnityEngine.Debug.Log("用户拒绝了消息订阅");
                    GuidePlayerOpenSetting();
                }
                else if (res.Values.First() == "ban")
                {
                    UnityEngine.Debug.Log("已被后台封禁");
                }
                else if (res.Values.First() == "filter")
                {
                    UnityEngine.Debug.Log("因模板标题相同而被过滤");
                }
            };
            requestSubscribeSystemMessageOption.fail = (res) =>
            {
                UnityEngine.Debug.Log("订阅接口调用失败");
                UnityEngine.Debug.Log(res.errMsg);
            };
            WX.RequestSubscribeSystemMessage(requestSubscribeSystemMessageOption);
#elif BYTEDANCEMINIGAME
#elif QGMINIGAME
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
#elif GOOGLE_PLAY
#else
#endif
#else
#endif
#else
#endif
        }

        //微信订阅体力消息
        public static void SubscribeVitalityMessage()
        {
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
#elif WEIXINMINIGAME
            UnityEngine.Debug.Log("我点在了订阅体力按钮的范围内");
            //尝试订阅一次性消息
            UnityEngine.Debug.Log("尝试订阅一次性消息");

            RequestSubscribeMessageOption requestSubscribeMessageOption = new RequestSubscribeMessageOption();
            requestSubscribeMessageOption.tmplIds = new string[] {
                    "wKSh_Fe69yuELqjWzQqhwy70t4O0IaS923r_AEqY4f4"
                };
            requestSubscribeMessageOption.success = (res) =>
            {
                UnityEngine.Debug.Log("订阅接口调用成功");

                if (res.Values.First() == "accept")
                {
                    UnityEngine.Debug.Log("用户允许了消息订阅");
                    subscribeVitalityCallBack?.Invoke();
                }
                else if (res.Values.First() == "reject")
                {
                    UnityEngine.Debug.Log("用户拒绝了消息订阅");
                    GuidePlayerOpenSetting();
                }
                else if (res.Values.First() == "ban")
                {
                    UnityEngine.Debug.Log("已被后台封禁");
                }
                else if (res.Values.First() == "filter")
                {
                    UnityEngine.Debug.Log("因模板标题相同而被过滤");
                }
            };
            requestSubscribeMessageOption.fail = (res) =>
            {
                UnityEngine.Debug.Log("订阅接口调用失败");
                UnityEngine.Debug.Log(res.errMsg);
            };
            WX.RequestSubscribeMessage(requestSubscribeMessageOption);
#elif BYTEDANCEMINIGAME
#elif QGMINIGAME
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
#elif GOOGLE_PLAY
#else
#endif
#else
#endif
#else
#endif
        }

        public static void SubscribeVitalityMessageInMainMenu()
        {
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
#elif WEIXINMINIGAME
            UnityEngine.Debug.Log("我点在了订阅体力按钮的范围内");
            //尝试订阅一次性消息
            UnityEngine.Debug.Log("尝试订阅系统消息");

            RequestSubscribeMessageOption requestSubscribeMessageOption = new RequestSubscribeMessageOption();
            requestSubscribeMessageOption.tmplIds = new string[] {
                    "wKSh_Fe69yuELqjWzQqhwy70t4O0IaS923r_AEqY4f4"
                };
            requestSubscribeMessageOption.success = (res) =>
            {
                UnityEngine.Debug.Log("订阅接口调用成功");

                if (res.Values.First() == "accept")
                {
                    UnityEngine.Debug.Log("用户允许了消息订阅");
                    //不知道为什么把移除Touch监听的方法写在这里并无效果，所以尝试由下面的回调触发
                    //RemoveTouchEndListener();
                    subscribeVitalityInMainMenuCallBack?.Invoke();
                }
                else if (res.Values.First() == "reject")
                {
                    UnityEngine.Debug.Log("用户拒绝了消息订阅");
                    GuidePlayerOpenSetting();
                }
                else if (res.Values.First() == "ban")
                {
                    UnityEngine.Debug.Log("已被后台封禁");
                }
                else if (res.Values.First() == "filter")
                {
                    UnityEngine.Debug.Log("因模板标题相同而被过滤");
                }
            };
            requestSubscribeMessageOption.fail = (res) =>
            {
                UnityEngine.Debug.Log("订阅接口调用失败");
                UnityEngine.Debug.Log(res.errMsg);
            };
            WX.RequestSubscribeMessage(requestSubscribeMessageOption);
#elif BYTEDANCEMINIGAME
#elif QGMINIGAME
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
#elif GOOGLE_PLAY
#else
#endif
#else
#endif
#else
#endif
        }

        //移除TouchEnd的所有监听
        public static void RemoveTouchEndListener()
        {
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
#elif WEIXINMINIGAME
            WX.OffTouchEnd();
#elif BYTEDANCEMINIGAME
#elif QGMINIGAME
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
#elif GOOGLE_PLAY
#else
#endif
#else
#endif
#else
#endif
        }

        //获取用户的订阅信息
        public static async UniTask<(bool isSubscribeVersion, bool isSubscribeVitality, string seeting2Value)> GetPlayerSubscribeInfo()
        {
            var completionSource = new UniTaskCompletionSource<(bool, bool, string)>();
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
            await UniTask.Yield();
            return (false, false, "reject");
#elif WEIXINMINIGAME
            UnityEngine.Debug.Log("尝试获取用户的订阅信息");
            GetSettingOption option = new GetSettingOption();
            option.withSubscriptions = true;
            option.success = (res) =>
            {
                UnityEngine.Debug.Log("获取用户的订阅信息成功");
                UnityEngine.Debug.Log(res.errMsg);
                bool isSubscribeVersion = false;
                bool isSubscribeVitality = false;
                string seeting2Value = "";
                if (res.subscriptionsSetting != null)
                {
                    UnityEngine.Debug.Log(res.subscriptionsSetting.itemSettings.Count);
                    if (res.subscriptionsSetting.itemSettings.Count > 0)
                    {
                        foreach (var item in res.subscriptionsSetting.itemSettings)
                        {
                            UnityEngine.Debug.Log(item.Key + "     " + item.Value);
                        }
                        if (res.subscriptionsSetting.itemSettings.TryGetValue("SYS_MSG_TYPE_WHATS_NEW", out string setting1))
                        {
                            if (setting1 == "accept")
                            {
                                UnityEngine.Debug.Log("用户目前正在订阅系统消息");
                                isSubscribeVersion = true;
                            }
                            else
                            {
                                UnityEngine.Debug.Log("setting的值为" + setting1);
                                UnityEngine.Debug.Log("用户并没有订阅系统消息，或者用户在订阅时没有勾选“总是保持以上选择，不再询问”");
                                isSubscribeVersion = false;
                            }
                        }
                        if (res.subscriptionsSetting.itemSettings.TryGetValue("wKSh_Fe69yuELqjWzQqhwy70t4O0IaS923r_AEqY4f4", out string setting2))
                        {
                            seeting2Value = setting2;
                            if (setting2 == "accept")
                            {
                                UnityEngine.Debug.Log("用户目前正在订阅体力消息");
                                isSubscribeVitality = true;
                            }
                            else
                            {
                                UnityEngine.Debug.Log("setting的值为" + setting2);
                                UnityEngine.Debug.Log("用户并没有订阅体力消息，或者用户在订阅时没有勾选“总是保持以上选择，不再询问”");
                                isSubscribeVitality = false;
                            }
                        }
                    }
                    else
                    {
                        UnityEngine.Debug.Log("没有找到用户订阅的系统或体力消息");
                        isSubscribeVersion = false;
                        isSubscribeVitality = false;
                    }
                }
                UnityEngine.Debug.Log("即将修正结果");
                completionSource.TrySetResult((isSubscribeVersion, isSubscribeVitality, seeting2Value));
                UnityEngine.Debug.Log("即将返回结果");
            };
            option.fail = (res) =>
            {
                UnityEngine.Debug.Log("获取用户的订阅信息失败");
                UnityEngine.Debug.Log(res.errMsg);
                completionSource.TrySetResult((false, false, ""));
            };
            WX.GetSetting(option);
            UnityEngine.Debug.Log("等待异步操作完成");
            return await completionSource.Task;
#elif BYTEDANCEMINIGAME
            await UniTask.Yield();
            completionSource.TrySetResult((false, false, ""));
            return await completionSource.Task;
#elif QGMINIGAME
            await UniTask.Yield();
            completionSource.TrySetResult((false, false, ""));
            return await completionSource.Task;
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
            await UniTask.Yield();
            return (false, false, "reject");
#elif GOOGLE_PLAY
            await UniTask.Yield();
            completionSource.TrySetResult((false, false, ""));
            return await completionSource.Task;
#else
#endif
#else
            await UniTask.Yield();
            completionSource.TrySetResult((false, false, ""));
            return await completionSource.Task;
#endif
#else
            await UniTask.Yield();
            completionSource.TrySetResult((false, false, ""));
            return await completionSource.Task;
#endif
        }

        //引导用户打开设置页开启通知
        public static void GuidePlayerOpenSetting()
        {
#if TEST_API || !UNITY_EDITOR
#if UNITY_WEBGL
#if NO_SDK
#elif WEIXINMINIGAME
            ShowModalOption showModalOption = new ShowModalOption();
            showModalOption.title = "提示";
            showModalOption.content = "请选择接收通知后再点击订阅按钮获取奖励";
            showModalOption.success = (res) =>
            {
                UnityEngine.Debug.Log("调用提示框成功");
                UnityEngine.Debug.Log(res.errMsg);
                OpenSettingOption openSettingOption = new OpenSettingOption();
                openSettingOption.withSubscriptions = true;
                openSettingOption.success = (res) =>
                {
                    UnityEngine.Debug.Log("调用打开设置接口成功");
                    UnityEngine.Debug.Log(res.errMsg);
                    UnityEngine.Debug.Log(res.subscriptionsSetting.itemSettings.Count);
                };
                openSettingOption.fail = (res) =>
                {
                    UnityEngine.Debug.Log("调用打开设置接口成功");
                    UnityEngine.Debug.Log(res.errMsg);
                };

                if (res.confirm)
                    WX.OpenSetting(openSettingOption);
            };
            showModalOption.fail = (res) =>
            {
                UnityEngine.Debug.Log("调用提示框失败");
                UnityEngine.Debug.Log(res.errMsg);
            };
            WX.ShowModal(showModalOption);
#elif BYTEDANCEMINIGAME
#elif QGMINIGAME
#else
#endif
#elif UNITY_ANDROID
#if NO_SDK
#elif GOOGLE_PLAY
#else
#endif
#else
#endif
#else
#endif
        }
    }
}
